﻿using System;
using System.Collections;
using Iesi.Collections;
using Nullables;

namespace PermissionBase.Core.Domain
{
	/// <summary>
	///	职员。
	/// </summary>
	public class Staff
	{
		private string _login_id;
	    private string _pkId;
		private string _password;
		private string _name;
        private string _compCode;
        private string _systemCode;
		private int _is_inner_user;
        private int _flagUse;
		private int _empBaseId;
	    private Department _defaultDepartment;
	    private User _user;
        private ISet _departments;
        private ISet _roles;
        private ISet _menus;
        private ISet _module_rights_grant;
        private ISet _module_rights_deny;

        #region 属性

        /// <summary>
		/// 登录ID。
		/// </summary>
        public virtual string LoginId
		{
			get { return _login_id; }
			set { _login_id = value; }
		}

	    public virtual User User
	    {
            get { return _user; }
            set { _user = value; }
	    }

        /// <summary>
        /// pkid 
        /// </summary>
	    public virtual string PkId
	    {
            get { return _pkId; }
            set { _pkId = value; }
	    }

		/// <summary>
		/// 登录密码。
		/// </summary>
        public virtual string Password
		{
			get { return _password; }
			set {  _password = value; }
		}
			
		
		/// <summary>
		/// 姓名。
		/// </summary>
        public virtual string Name
		{
			get { return _name; }
			set { _name = value; }
		}
			
		
			
		/// <summary>
		/// 公司编号。
		/// </summary>
        public virtual string CompCode
		{
            get { return _compCode; }
            set { _compCode = value; }
		}
			
	    /// <summary>
		/// 系统编号。
		/// </summary>
        public virtual string SystemCode
        {
            get { return _systemCode; }
            set { _systemCode = value; }
        }
			
		
			
		/// <summary>
		/// 是否内置用户。
		/// </summary>
        public virtual int IsInnerUser
		{
			get { return _is_inner_user; }
			set { _is_inner_user = value; }
		}
			
		/// <summary>
		/// 是否在职的标识，0表示在职，1表示停用；
		/// </summary>
        public virtual int FlagUse
		{
			get{ return _flagUse; }
			set{_flagUse = value;}
		}
			
		/// <summary>
		/// 排序ID。
		/// </summary>
        public virtual int EmpBaseId
		{
			get { return _empBaseId; }
			set { _empBaseId = value; }
        }


        /// <summary>
        /// 所属部门。可能是多个。
        /// </summary>
        public virtual Department DefaultDepartment
        {
            get 
            {
                IEnumerator en = this.Department.GetEnumerator();
                if (en.MoveNext())
                {
                    _defaultDepartment = en.Current as Department;
                    return _defaultDepartment;
                }
                else
                {
                    return null;
                }
                
            }
            set { _defaultDepartment = value; }
        }

        
        
        /// <summary>
        /// 所属部门。可能是多个。
        /// </summary>
        public virtual ISet Department
        {
            get { return _departments; }
            set { _departments = value; }
        }

        /// <summary>
        /// 角色列表。
        /// </summary>
        public virtual ISet Roles
        {
            get { return _roles; }
            set { _roles = value; }
        }

        /// <summary>
        /// 按人员授权能访问的菜单。
        /// </summary>
        public virtual ISet Menus
        {
            get { return _menus; }
            set { _menus = value; }
        }

        /// <summary>
        /// 对当前职员进行了肯定授权的模块权限。
        /// </summary>
        public virtual ISet ModuleRightsGrant
        {
            get { return _module_rights_grant; }
            set { _module_rights_grant = value; }
        }

        /// <summary>
        /// 对当前职员进行了否定授权的模块权限。
        /// </summary>
        public virtual ISet ModuleRightsDeny
        {
            get { return _module_rights_deny; }
            set { _module_rights_deny = value; }
        }
				
		#endregion 

        #region 构造函数

        public Staff()
		{
			_login_id = String.Empty;
			_password = String.Empty; 
			_systemCode = String.Empty; 
			_name = String.Empty;
            _compCode = String.Empty; 
			_is_inner_user = 0; 
			_flagUse = 0;
			_empBaseId = 0;
            _defaultDepartment = null;
            _roles = new HashedSet();
            _module_rights_grant = new HashedSet();
            _module_rights_deny = new HashedSet();
		}

		#endregion

        #region 公共方法


        /// <summary>
        /// 移动职员。
        /// </summary>
        /// <param name="newParent">新的部门。</param>
        public void MoveTo(Department newParent)
        {
            Department oldParent = this.DefaultDepartment;
            //2009-08-19 multi system problem
//            oldParent.Staff.Remove(this);
//            newParent.Staff.Add(this);
            this.DefaultDepartment = newParent;
        }


        /// <summary>
        /// 删除对当前职员所有的模块授权。
        /// </summary>
        public void RemoveAllPermissions()
        {
            //删除模块肯定授权。
            foreach(ModuleRight grant in this.ModuleRightsGrant)
            {
                grant.StaffGrant.Remove(this);
            }
            this.ModuleRightsGrant.Clear();

            //删除模块否定授权。
            foreach(ModuleRight deny in this.ModuleRightsDeny)
            {
                deny.StaffDeny.Remove(this);
            }
            this.ModuleRightsDeny.Clear();
        }


        /// <summary>
        /// 与所有的角色脱离关联。
        /// </summary>
        public void BreakAwayFromRoles()
        {
            foreach(Role role in this.Roles)
            {
                role.Staff.Remove(this);
            }
            this.Roles.Clear();
        }


        /// <summary>
        /// 从所属部门脱离。
        /// </summary>
        public void BreakAwayFromDepartment()
        {
            Department d = this.DefaultDepartment;
            this.DefaultDepartment = null;
            //2009-08-19 multi system problem
//            d.Staff.Remove(this);
        }


        /// <summary>
        /// 判断职员是否对某一项模块权限拥有肯定授权。
        /// </summary>
        /// <remarks>
        /// 授权判断顺序如下：
        /// （1）职员是否为内置用户。如果是则返回true，否则执行下一步。
        /// （2）职员本身是否对此权限做了否定授权。如果是则返回false，否则执行下一步。
        /// （3）职员本身是否对此权限做了肯定授权。如果是则返回true，否则执行下一步。
        /// （4）职员拥有的所有角色的集合中，是否有任何一个角色对此权限做了否定授权。如果是则返回false，否则执行下一步。
        /// （5）职员拥有的所有角色的集合中，是否有任何一个角色对此权限做了肯定授权。如果是则返回true，否则执行下一步。
        /// （6）返回false。（即职员不是内置用户，并且职员本身以及职员拥有的所有角色都没有提供对此权限的任何授权信息。）
        /// </remarks>
        /// <param name="moduleRight">模块权限。</param>
        /// <returns>是否有肯定授权。</returns>
        public bool HasGrantPermission(ModuleRight moduleRight)
        {
            if(this.IsInnerUser == 1) return true;

            if (this.ModuleRightsDeny.Contains(moduleRight)) return false;
            if (this.ModuleRightsGrant.Contains(moduleRight)) return true;

            bool hasRoleGrant = false;
            foreach (Role role in this.Roles)
            {
                if (role.ModuleRightsDeny.Contains(moduleRight)) return false;
                if (role.ModuleRightsGrant.Contains(moduleRight)) hasRoleGrant = true;
            }

            return hasRoleGrant;
        }


        /// <summary>
        /// 获取对于某模块的所有肯定授权的权限标示。
        /// </summary>
        /// <param name="module">模块。</param>
        /// <returns>权限标示集合。</returns>
        public ArrayList GetGrantPermissions(Module module)
        {
            ArrayList alPermissions = new ArrayList();

            IDictionaryEnumerator ide = module.ModuleRights.GetEnumerator();
            while (ide.MoveNext())
            {
                ModuleRight mr = ((DictionaryEntry)ide.Current).Value as ModuleRight;
                if (this.HasGrantPermission(mr))
                {
                    alPermissions.Add(mr.RightTag);
                }
            }

            return alPermissions;
        }


        #endregion

    }
}
